/**
 * @Created by Webstorm
 * @Author: 打字桶
 * @Desc
 */
// 从v2.11.2起，SDK 支持了 WebSocket，推荐接入；v2.10.2及以下版本，使用 HTTP
import TIM from 'tim-wx-sdk-ws';
import TIMUploadPlugin from 'tim-upload-plugin';
import timConfig from "../config/tim";
import User from "./user";
import genTestUserSig from "../lib/tim/generate-test-usersig";

// 单例模式
class Tim {
  /**
   * 用注释的方法，将@type括号中的内容改为类名，使IDE识别单例模式，实现语法自动匹配
   * @type {Tim}
   */
  static instance = null
  _SDKInstance = null
  _nextReqMessageID = null //做分页拉取时使用
  _messageList = []

  constructor() {
    // 创建 SDK 实例，`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
    let tim = TIM.create(timConfig.options); // SDK 实例通常用 tim 表示
    // 设置 SDK 日志输出级别，详细分级请参见 <a href="https://web.sdk.qcloud.com/im/doc/zh-cn//SDK.html#setLogLevel">setLogLevel 接口的说明</a>
    tim.setLogLevel(timConfig.logLevel); // 普通级别，日志量较多，接入时建议使用
    // tim.setLogLevel(1); // release 级别，SDK 输出关键信息，生产环境时建议使用
    // 注册腾讯云即时通信 IM 上传插件
    tim.registerPlugin({'tim-upload-plugin': TIMUploadPlugin});
    // 实例保存到类属性中
    this._SDKInstance = tim
  }

  // 单例模式一般都有获取实例的方法
  static getInstance() {
    if (!Tim.instance) {
      Tim.instance = new Tim()
    }
    return Tim.instance
  }

  getSDK() {
    return this._SDKInstance
  }

  // 登录
  login() {
    const userInfo = User.getUserInfoByLocal()
    const textUserSig = genTestUserSig(userInfo.id.toString())
    this._SDKInstance.login({
      userID: userInfo.id.toString(),
      userSig: textUserSig.userSig//教学阶段前端生成，实际要后端生成
    })
  }

  // 登出
  logout() {
    this._SDKInstance.logout()
  }

  // 获取用户信息
  async getUserProfile(targetUserId) {
    const res = await this._SDKInstance.getUserProfile({
      userIDList: [targetUserId]
    })
    return res.data
  }

  // 更新用户信息
  async updateUserProfile(userInfo) {
    await this._SDKInstance.updateMyProfile({
      nick: userInfo.nickname,
      avatar: userInfo.avatar,
      gender: userInfo.gender === 1 ? TIM.TYPES.GENDER_MALE : TIM.TYPES.GENDER_FEMALE
    })
  }

  // 获取会话列表
  async getConversationList() {
    const res = await this._SDKInstance.getConversationList()
    return res.data.conversationList
  }

  // 获取消息列表
  async getMessageList(targetUserId, count = 10) {
    // 进入即判断是否加载完毕
    if (this.isCompleted) {
      return this._messageList
    }
    // 上划加载更多
    //官方文档 客户端API SDKAPI(Web&小程序) 会话 getMessageList
    const res = await this._SDKInstance.getMessageList({
      // 必选参数 3个
      conversationID: `C2C${targetUserId}`, // 单聊C2C
      nextReqMessageID: this._nextReqMessageID, // 分页参数
      count: count > 15 ? 15 : count
    })
    this._nextReqMessageID = res.data.nextReqMessageID
    this.isCompleted = res.data.isCompleted
    this._messageList = res.data.messageList
    return this._messageList
  }

  // 设置消息已读
  async setMessageRead(targetUserId) {
    const res = await this._SDKInstance.setMessageRead({
      conversationID: `C2C${targetUserId}`
    })
    return res
  }

  // 根据不同类型，创建不同实例
  createMessage(type, content, targetUserId, extension = null) {
    let message
    const params = {
      to: targetUserId,
      conversationType: TIM.TYPES.CONV_C2C,
      payload: null
    }
    // 工厂模式
    switch (type) {
      case TIM.TYPES.MSG_TEXT:
        params.payload = {text: content}
        message = this._SDKInstance.createTextMessage(params)
        break
      case TIM.TYPES.MSG_IMAGE:
        params.payload = {file: content}
        message = this._SDKInstance.createImageMessage(params)
        break
      case TIM.TYPES.MSG_CUSTOM:
        params.payload = {
          data: 'service',
          description: JSON.stringify(content),
          extension
        }
        message = this._SDKInstance.createCustomMessage(params)
        break
      default:
        throw Error('未知消息类型')
    }
    return message
  }

  // 发送消息
  async sendMessage(message) {
    const res = await this._SDKInstance.sendMessage(message)// 传递实例 具体参考tim文档
    return res.data
  }

  // 重置会话消息
  reset() {
    this._nextReqMessageID = ''
    this.isCompleted = false
    this._messageList = []
    return this
  }
}

export default Tim
 
 